package com.hongkuncheng.cms.controller.admin.system;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import javax.imageio.ImageIO;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hongkuncheng.cms.helper.SecurityHelper;
import org.hibernate.sql.JoinType;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Controller;
import com.hongkuncheng.cms.controller.BaseController;
import com.hongkuncheng.cms.helper.DataHelper;
import com.hongkuncheng.cms.helper.HttpHelper;
import com.hongkuncheng.cms.helper.TokenHelper;
import com.hongkuncheng.cms.model.Admin;
import com.hongkuncheng.cms.model.Article;
import com.hongkuncheng.cms.model.ArticleState;
import com.hongkuncheng.cms.model.Checkflow;
import com.hongkuncheng.cms.model.Checknode;
import com.hongkuncheng.cms.model.ChecknodeReAdmin;
import com.hongkuncheng.cms.model.Checkrecord;
import com.hongkuncheng.cms.model.CheckrecordResult;
import com.hongkuncheng.cms.model.Imagesize;
import com.hongkuncheng.cms.model.Organization;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 系统对话框
 *
 * @author 洪坤成
 */
@Controller
@Transactional
@RequestMapping("admin/system/dialog")
public class AdialogController extends BaseController {

    //////////////////////////////////////// 审核流程 ////////////////////////////////////////

    // 获取当前用户参与的审核流程
    @RequestMapping("getcheckflow")
    public String getcheckflow() {
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        List<ChecknodeReAdmin> cras = factorySession.createCriteria(ChecknodeReAdmin.class)
                .createAlias("checknode", "checknode", JoinType.LEFT_OUTER_JOIN)
                .add(Restrictions.eq("checknode.checknodeType.id", 1))
                .add(Restrictions.eq("admin.id", admin.getId())).list();
        List<Checkflow> checkflows = new ArrayList<Checkflow>();
        for (ChecknodeReAdmin cra : cras)
            if (cra.getChecknode().getCheckflow().isActive() && !checkflows.contains(cra.getChecknode().getCheckflow()))
                checkflows.add(cra.getChecknode().getCheckflow());
        request.setAttribute("checkflows", checkflows);
        List<Checknode[]> checkflownodes = new ArrayList<Checknode[]>();
        for (Checkflow checkflow : checkflows) {
            Checknode[] checknodes = new Checknode[checkflow.getChecknodes().size()];
            for (Checknode checknode : checkflow.getChecknodes()) checknodes[checknode.getSort()] = checknode;
            checkflownodes.add(checknodes);
        }
        request.setAttribute("checkflownodes", checkflownodes);
        request.setAttribute("articleids", request.getParameter("articleids"));
        request.setAttribute("publishmethord", request.getParameter("publishmethord"));
        return view();
    }

    // 设置审核流程记录
    @RequestMapping("setcheckrecord")
    @ResponseBody
    public void setcheckrecord() {
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        admin = factorySession.get(Admin.class, admin.getId());
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        Checkflow checkflow = factorySession.get(Checkflow.class, checkflowId);
        String[] articleIds = request.getParameter("articleids").split(",");
        List<Article> articles = factorySession.createCriteria(Article.class)
                .add(Restrictions.in("id", DataHelper.convertToIntegerArray(articleIds)))
                .list();
        ArticleState articleState = factorySession.load(ArticleState.class, 3);
        List<Checknode> checknodes = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", checkflowId))
                .addOrder(Order.asc("sort")).setMaxResults(2).list();
        for (Article article : articles) {
            article.setArticleState(articleState);
            article.setCheckflowId(checkflowId);
            article.setChecknode(checknodes.get(1));
            // 清除该文档原来有的流程记录
            List<Checkrecord> checkrecords = factorySession.createCriteria(Checkrecord.class)
                    .add(Restrictions.eq("article.id", article.getId())).list();
            for (Checkrecord checkrecord : checkrecords) factorySession.delete(checkrecord);
            // 创建新的流程记录
            Checkrecord checkrecord = new Checkrecord();
            checkrecord.setArticle(article);
            checkrecord.setAdmin(admin);
            checkrecord.setChecknode(checknodes.get(0));
            checkrecord.setOpinion("发起" + checkflow.getName());
            checkrecord.setSubmittime(new Date());
            factorySession.save(checkrecord);
        }
    }

    // 流程跟踪
    @RequestMapping("checkflowtrack")
    public String checkflowtrack() {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        request.setAttribute("article", article);
        List<Checknode> checknodes = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", article.getCheckflowId()))
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("checknodes", checknodes);
        List<Checkrecord> checkrecords = factorySession.createCriteria(Checkrecord.class)
                .add(Restrictions.eq("article.id", articleId))
                .addOrder(Order.asc("id")).list();
        request.setAttribute("checkrecords", checkrecords);
        if (article.getChecknode() != null && !article.getChecknode().isSingleaudit()) {
            // 会审
            // 获取审核记录集里和当前节点不同的最大ID值
            Object uniqueResult = factorySession.createCriteria(Checkrecord.class)
                    .add(Restrictions.eq("article.id", article.getId()))
                    .add(Restrictions.or(Restrictions.and(Restrictions.isNotNull("checknode"),
                            Restrictions.ne("checknode.id", article.getChecknode().getId())),
                            Restrictions.and(Restrictions.isNull("checknode"),
                                    Restrictions.eq("checkrecordResult.id", 3))))
                    .setProjection(Projections.max("id")).uniqueResult();
            int neqmaxId = uniqueResult == null ? 0 : Integer.parseInt(uniqueResult.toString());
            // 获取当前文档当前审核节点已经参与审核的人员
            List<Checkrecord> huicheckrecords = factorySession.createCriteria(Checkrecord.class)
                    .add(Restrictions.eq("article.id", articleId))
                    .add(Restrictions.eq("checknode.id", article.getChecknode().getId()))
                    .add(Restrictions.gt("id", neqmaxId)).list();
            // 已经参与会审的人员的ID集合
            List<Integer> huicheckadminIds = new ArrayList<Integer>();
            for (Checkrecord checkrecord : huicheckrecords) huicheckadminIds.add(checkrecord.getAdmin().getId());
            request.setAttribute("huicheckadminids", huicheckadminIds);
        }
        return view();
    }

    // 流程跳转
    @RequestMapping("checkflowjump")
    public String checkflowjump() {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        request.setAttribute("article", article);
        List<Checknode> checknodes = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", article.getCheckflowId()))
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("checknodes", checknodes);
        return view();
    }

    // 流程跳转处理
    @RequestMapping("checkflowjumpdo")
    @ResponseBody
    public void checkflowjumpdo() {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        int checknodeId = Integer.parseInt(request.getParameter("checknodeid"));
        int result = 0;
        switch (checknodeId) {
            case -1: // 草稿状态
                article.setArticleState(factorySession.load(ArticleState.class, 1));
                article.setCheckflowId(null);
                article.setChecknode(null);
                List<Checkrecord> checkrecords = factorySession.createCriteria(Checkrecord.class).list();
                for (Checkrecord checkrecord : checkrecords) factorySession.delete(checkrecord);
                break;
            case 0: // 发布状态
                article.setArticleState(factorySession.load(ArticleState.class, 4));
                article.setChecknode(null);
                result = 1;
                break;
            default: // 其它节点
                article.setChecknode(factorySession.load(Checknode.class, checknodeId));
                break;
        }
        if (checknodeId > -1) {
            Admin admin = (Admin) request.getSession().getAttribute("admin");
            Checkrecord checkrecord = new Checkrecord();
            checkrecord.setArticle(article);
            checkrecord.setAdmin(admin);
            checkrecord.setCheckrecordResult(factorySession.load(CheckrecordResult.class, 3));
            checkrecord.setOpinion(checknodeId == 0 ? "发布" : article.getChecknode().getName());
            checkrecord.setSubmittime(new Date());
            factorySession.save(checkrecord);
        }
        print(result);
    }

    //////////////////////////////////////// 文档报送 ////////////////////////////////////////

    // 文档报送
    @RequestMapping("articlepush")
    public String articlepush() {
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        List<Organization> orgtemps = factorySession.createCriteria(Organization.class)
                .add(Restrictions.eq("attach", true))
                .addOrder(Order.asc("sort")).list();
        Organization org = null;
        List<Organization> organizations = new ArrayList<Organization>();
        for (Organization orgtemp : orgtemps) {
            if (orgtemp.getProject().equals(applicationName)) org = orgtemp;
            else organizations.add(orgtemp);
        }
        request.setAttribute("organizations", organizations);
        String[] articleids = request.getParameter("articleids").split(",");
        List<Article> articles = factorySession.createCriteria(Article.class)
                .add(Restrictions.in("id", DataHelper.convertToIntegerArray(articleids)))
                .list();
        JSONArray array = new JSONArray();
        for (Article article : articles) {
            JSONObject obj = new JSONObject();
            String title = SecurityHelper.aesEncrypt(article.getTitle());
            obj.put("title", title);
            obj.put("source", SecurityHelper.aesEncrypt(org.getName()));
            obj.put("author", SecurityHelper.aesEncrypt(article.getAuthor()));
            obj.put("digest", SecurityHelper.aesEncrypt(article.getDigest()));
            obj.put("exturl", SecurityHelper.aesEncrypt(article.getExturl()));
            obj.put("contents", SecurityHelper.aesEncrypt(article.getContents()));
            if (article.getImage() != null && !article.getImage().isEmpty()) {
                if (article.getImage().startsWith("/upload/"))
                    article.setImage(org.getOutterhost() + article.getImage());
                obj.put("image", SecurityHelper.aesEncrypt(article.getImage()));
            }
            obj.put("pusher", SecurityHelper.aesEncrypt(admin.getName()));
            array.add(obj);
        }
        request.setAttribute("articlecount", array.size());
        request.setAttribute("articlejsondata", array.toString().replace("\"", "'"));
        return view();
    }

    // 文档报送处理
    @RequestMapping("articlepushdo")
    @ResponseBody
    public void articlepushdo() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("token", TokenHelper.generate());
        params.put("articlejsondata", request.getParameter("articlejsondata").replace("'", "\""));
        String result = null;
        try {
            result = HttpHelper.post(request.getParameter("url") + "/interfaces/organization/receivepush", params);
        } catch (Exception e) {
            e.printStackTrace();
            result = "0";
            println(e.getMessage());
        }
        print(result);
    }

    //////////////////////////////////////// 图片裁切 ////////////////////////////////////////

    // 图片裁切
    @RequestMapping("imagecrop")
    public String imagecrop() {
        String filepath = request.getParameter("filepath");
        List<Imagesize> imagesizes = null;
        String width = request.getParameter("width");
        String height = request.getParameter("height");
        if (width != null && height != null) {
            imagesizes = new ArrayList<Imagesize>();
            String description = request.getParameter("description");
            Imagesize imagesize = new Imagesize();
            imagesize.setWidth(Integer.parseInt(width));
            imagesize.setHeight(Integer.parseInt(height));
            imagesize.setDescription(description);
            imagesizes.add(imagesize);
        } else {
            imagesizes = factorySession.createCriteria(Imagesize.class)
                    .addOrder(Order.asc("id")).list();
        }
        request.setAttribute("filepath", filepath);
        float sizeX = (float) imagesizes.get(0).getWidth();
        float sizeY = (float) imagesizes.get(0).getHeight();
        request.setAttribute("rateX", sizeX * (1 / sizeY));
        File srcFile = new File(applicationDirectory + filepath);
        Image srcImg = null;
        try {
            srcImg = ImageIO.read(srcFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        float imgWidth = (float) srcImg.getWidth(null);
        float imgHeight = (float) srcImg.getHeight(null);
        request.setAttribute("size", imgWidth > imgHeight ? "width" : "height");
        request.setAttribute("marintop", imgWidth > imgHeight ? (300 - imgHeight * (300 / imgWidth)) / 2 : 0);
        request.setAttribute("imagesizes", imagesizes);
        return view();
    }

    // 图片裁切处理
    @RequestMapping("imagecropcut")
    @ResponseBody
    public void imagecropcut() {
        String filepath = request.getParameter("filepath");
        int pnlWidth = Integer.parseInt(request.getParameter("pnlWidth"));
        int pnlHeight = Integer.parseInt(request.getParameter("pnlHeight"));
        int preWidth = Integer.parseInt(request.getParameter("preWidth"));
        int startX = Integer.parseInt(request.getParameter("startX"));
        int startY = Integer.parseInt(request.getParameter("startY"));
        int iWidth = Integer.parseInt(request.getParameter("iWidth"));
        OutputStream os = null;
        String srcPath = applicationDirectory + filepath;
        File srcFile = new File(srcPath);
        Image srcImg = null;
        try {
            srcImg = ImageIO.read(srcFile);
            int imgSrcWidth = srcImg.getWidth(null);
            int imgSrcHeight = srcImg.getHeight(null);
            float rate = (float) imgSrcWidth / preWidth;
            BufferedImage buffImg = new BufferedImage(pnlWidth, pnlHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = buffImg.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            int imgScaledWidth = (int) (imgSrcWidth / ((float) iWidth / pnlWidth * rate));
            int imgScaledHeight = (int) (imgSrcHeight / ((float) iWidth / pnlWidth * rate));
            g.drawImage(srcImg.getScaledInstance(imgScaledWidth, imgScaledHeight, Image.SCALE_SMOOTH),
                    0 - (int) (imgScaledWidth * startX / (imgSrcWidth / rate)),
                    0 - (int) (imgScaledHeight * startY / (imgSrcHeight / rate)), null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();
            os = new FileOutputStream(srcPath);
            ImageIO.write(buffImg, "JPG", os);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
